import axios from 'axios';

/* 创建axios实例 */
const service = axios.create({
  timeout: 30000, // 请求超时时间
  withCredentials: true,
});

/* request拦截器 */
service.interceptors.request.use(
  (config) => {
    if (config.url && /^https?:\/\//.test(config.url)) {
      config.baseURL = '';
    }
    // debounce 配置项，防抖
    if (config.debounce) {
      // 生成cancelToken
      config.cancelToken = new CancelToken((handleCancel) => {
        removePending(config, handleCancel);
      });
    }

    config.headers = !(() => {
      let custom_headers = {
        credentials: 'include'
      };
      if (config.data instanceof FormData) {
        custom_headers['Content-Type'] = 'multipart/form-data';
      }
      return {
        ...custom_headers,
        ...config.headers
      };
    });
    return config;
  },
  (error) => {
    Promise.reject(error);
  }
);

/* respone拦截器 */
service.interceptors.response.use(
  (response) => {
    // 移除队列中的该请求
    removePending(response.config);
    const res = response.data;
    if (response.status >= 400) {
      throw new Error(
        JSON.stringify({
          code: response.status,
          message: response.statusText
        })
      );
    }
    if (res.errcode || res.errno) {
      // 错误处理
    }
    return Promise.resolve(res);
  },
  (error) => {
    // 异常处理
    if (error.message === '取消重复请求') {
      return Promise.reject(error);
    }
    return Promise.reject(error);
  }
);

/* 防止重复提交，利用axios的cancelToken */
let pending = [];
const CancelToken = axios.CancelToken;

const removePending = (config, handleCancel) => {
  // 获取请求的url
  const flagUrl = config.url;
  // 判断该请求是否在请求队列中
  if (flagUrl) {
    if (pending.indexOf(flagUrl) !== -1) {
      // 如果在请求中，并存在f,f即axios提供的取消函数
      if (handleCancel) {
        handleCancel('取消重复请求'); // 执行取消操作
      } else {
        pending.splice(pending.indexOf(flagUrl), 1); // 把这条记录从数组中移除
      }
    } else {
      // 如果不存在在请求队列中，加入队列
      if (handleCancel) {
        pending.push(flagUrl);
      }
    }
  }
};

export function get(
  url,
  params,
  options
) {
  return service({
    ...{ options },
    url,
    method: 'GET',
    params
  });
}

export function post(
  url,
  params,
  options
) {
  return service({
    ...{ options },
    url,
    method: 'POST',
    params
  });
}